//深度遍历ast
//新增一个context，为后续埋伏笔！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
function traverserNode(ast, context) {
    //直接修改原始数据？？感觉不大好
    context.currentNode = ast;
    //context.nodeTransforms是一个数组，其中的每一个元素都是一个函数
    const transforms = context.nodeTransforms;
    //把原来的具体操作内容抽象出去
    for (let i = 0; i < transforms.length; i++) {
        transforms[i](context.currentNode, context);
    }

    //如果有子节点，则递归地调用traverseNode函数进行遍历
    const children = context.currentNode.children;
    if (children) {
        for (let i = 0; i < children.length; i++) {
            //在转换之前，将单节点设置为父节点
            context.parent = context.currentNode;
            context.childIndex = i;
            traverserNode(children[i], context);
        }
    }
}
//标签替换转换
function transformElement(node) {
    if (node.type == "Element" && node.tag == "p") {
        //见所有的p标签转换成"h1";
        node.tag = "h1";
    }
}
//文本替换转换
function transformText(node, context) {
    if (node.type === "Text") {
        //  node.content = node.content.repeat(2);
        context.replaceNode({
            type: "Element",
            tag: "span",
        });
    }
}

//封装transform函数，来对AST进行转换
function transform(ast) {
    const context = {
        //添加currentNode，用来存储当前正在转换的节点
        currentNode: null,
        childIndex: 0,
        parent: null,
        nodeTransforms: [transformElement, transformText],
        //用来替换节点的函数，接受新的节点座位参数
        replaceNode(node) {
            /**
             * 为了替换跌点我们需要修改AST
             * 找到当前节点在父节点的children中的位置，context.childIndex
             * 然后使用新节点替代
             */
            context.parent.children[context.childIndex] = node;
            //由于当前节点呗新的节点体寒掉了，因此我们需要将currentNode更新为新节点
            context.currentNode = node;
        },
    };
    traverserNode(ast, context);
    console.log(dump(ast));
}